package com.kharthick.game;

import java.applet.Applet;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import com.kharthick.pwGame.map.Environment;
import com.kharthick.pwGame.map.Map;
import com.kharthick.pwGame.map.Tile;
import com.kharthick.pwGame.players.Player;
import com.kharthick.pwGame.rules.*;
import com.kharthick.pwGame.units.*;

public class Core extends Applet implements 
Runnable, MouseListener, MouseMotionListener, KeyListener {
	
	public static final int TILE_SIZE = 50;
	private static final long serialVersionUID = 4300370483474176231L;
	
	List<Map> maps;
	List<Player> players;
	Player currentPlayer;
	Environment currentEnv;
	Map currentMap;
	Player p1, p2;
	Unit s, a;
	Unit ActiveUnit;
	MediaTracker tracker;
	Thread core;
	Rules move, attack;
	Menu menu;
	
	private int mouseX, mouseY;
	private int pressedKey;
	private char typedKey;
	private String mapName;
	private int numberOfPlayers;	
	int gameState;
	
	
	
    // The object we will use to write with instead of the standard screen graphics
    Graphics bufferGraphics;
    // The image that will contain everything that has been drawn on bufferGraphics.
    Image offscreen;
    Dimension dim;

	
	public void start() {
		//currentEnv = new Environment("test.xml", 2, TILE_SIZE, tracker);
		//currentMap = currentEnv.getMap();
		//players = currentEnv.getPlayers();
		
		//if(null == currentMap){
		//	System.out.println("Map not found");
		//}
		
		//this.setBackground(Color.black);
		gameState = 0;
		mapName = "test.xml";
		numberOfPlayers = 2;
		
		menu = new Menu((Graphics2D) bufferGraphics, tracker, this);
		
		move = new MoveRules();
		attack = new AttackRules();
		
		core = new Thread(this);
		core.start();
	}
	
	public void run() {
		System.out.println("Hi");
		//int count = 0;
		while(core != null){
			try{
				core.sleep(100);
				//System.out.print(count);
				//count++;
			} catch (InterruptedException e) {}
			bufferGraphics.clearRect(0,0,dim.width,dim.width);
			//System.out.println(gameState);
			switch(gameState){
				//Initialize the menu
				case 0:
					
					menu.initial();
					gameState = 1;
					//break;
				//Menu waiting for responses
				case 1:
					if(typedKey == ' '){
						mapName = menu.getMapName();
						numberOfPlayers = menu.getNumberOfPlayers();
						typedKey = 0; //bad hack, must be fixed
						gameState = 2;
					}
					//System.out.println(pressedKey);
					menu.menuWait(pressedKey);
					pressedKey = 0;
					break;
				//Initialize game
				case 2:
					currentEnv = new Environment(mapName, numberOfPlayers, TILE_SIZE, tracker);
					currentMap = currentEnv.getMap();
					players = currentEnv.getPlayers();
					if(null == currentMap){
						System.out.println("The map selected is not a properly formated Primitive Wars map.");
						menu.draw();
						gameState = 1;
					}
					else
						gameState = 3;
					break;
				case 3:
					if(typedKey == 'm'){
						//System.out.println(getBackground().toString());
						//setBackground(Color.white);
						//System.out.println(getBackground().toString());
						gameState = 0;
						typedKey = 0; //bad hack again
					}
					currentPlayer = players.get(0);
					if(null != ActiveUnit){
						//System.out.println("ActiveUnit not null");
						//System.out.println(move.actionOk(ActiveUnit, mouseX, mouseY, players));
						//System.out.println(attack.actionOk(ActiveUnit, mouseX, mouseY, players));
						
						if(move.actionOk(ActiveUnit, mouseX, mouseY, players)){
							System.out.println("move");
							move.doAction(currentMap);
							ActiveUnit = null;
							//repaint();
						}
						else if(attack.actionOk(ActiveUnit, mouseX, mouseY, players)){
							System.out.println("attack");
							attack.doAction(currentMap);
							ActiveUnit = null;
							//repaint();
						}
					}
					drawEnvironment();
					break;
			}
			repaint();
			//System.out.println(getBackground().toString());
			//System.out.println(((Graphics2D) bufferGraphics).getBackground().toString());
		}
		System.out.println("Bye");
	}
	
	public void init() {
		setSize(500, 400);
		
		//Set background color
		setBackground(Color.black);
		
		//Initiate tracker to wait for image load
		tracker = new MediaTracker(this);
		
		//add mouse listeners
		addMouseListener(this);
		addMouseMotionListener(this);
		addKeyListener(this);
		
        // Create an offscreen buffer
		dim = getSize();
        offscreen = createImage(dim.width,dim.height);
        bufferGraphics = offscreen.getGraphics();
        repaint();
	}
	
	public void drawEnvironment(){
		currentMap.draw(bufferGraphics);
   	 	//System.out.println("drawmap");
   	 	
   	 	for(Iterator it = players.iterator(); it.hasNext(); ) {
			Player p = (Player) it.next();
			p.drawDeadUnits(bufferGraphics);
		}
   	 	for(Iterator it = players.iterator(); it.hasNext(); ) {
			Player p = (Player) it.next();
			p.drawUnits(bufferGraphics);
		}
	}
	
	public void paint(Graphics g){
   	 	//bufferGraphics.clearRect(0,0,dim.width,dim.width);
   	 	
		g.drawImage(offscreen,0,0,this);
	}
	
    public void update(Graphics g)
    {
         paint(g);
    }

	public void mouseClicked(MouseEvent me) {
		/*
		if(getBackground().equals(Color.black)){
			setBackground(Color.white);
		}
		else
			setBackground(Color.black);
		
		//Why doesnt background color change??
		if(((Graphics2D) bufferGraphics).getBackground().equals(Color.black)){
			((Graphics2D) bufferGraphics).setBackground(Color.white);
		}
		else
			((Graphics2D) bufferGraphics).setBackground(Color.black);
			*/
		if(gameState == 3){
		Tile t = currentMap.getTileByScreenPosition(me.getX(), me.getY());
		//System.out.println("currentPlayer="+currentPlayer);
		Unit u = currentPlayer.getUnitByScreenPosition(me.getX(), me.getY());
		
		
		/*Unit u = null;
		for(Iterator it = players.iterator(); it.hasNext(); ) {
			boolean oneSelected = false;
			Player p = (Player) it.next();
			if(null != p.getUnitByScreenPosition(me.getX(), me.getY())){
				u = p.getUnitByScreenPosition(me.getX(), me.getY());
				oneSelected = true;
			}
			if(oneSelected = false)
				u = null;				
		}*/
		
		mouseX = me.getX();
		mouseY = me.getY();
		if(null != t) {
			switch (me.getButton()) {
				case MouseEvent.BUTTON1:
					t.leftClick();
					break;
				case MouseEvent.BUTTON2:
				case MouseEvent.BUTTON3:
					t.rightClick();
					break;
			}
			
			repaint();
		}
		if(null != u){
			switch (me.getButton()) {
				case MouseEvent.BUTTON1:
					u.leftClick();
					ActiveUnit = u;
					break;
			}
		}
		}
	}

	public void mousePressed(MouseEvent me) {
		// TODO Auto-generated method stub
		
	}

	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void mouseDragged(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void mouseMoved(MouseEvent me) {
		if(gameState == 3){
			Tile t = currentMap.getTileByScreenPosition(me.getX(), me.getY());
			if(null != t) {
				t.mouseOver();
				//repaint();
			}
		}
	}

	public void keyTyped(KeyEvent key) {
		typedKey = key.getKeyChar();
		System.out.println(typedKey);
		
	}

	public void keyPressed(KeyEvent key) {
		pressedKey = key.getKeyCode();
		System.out.println(pressedKey);
		
	}

	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	} 
	
}
